package com.restaurant.application.indexes.consumptionlist.mysql;

import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.nebutown.base.Unit;
import com.nebutown.description.data.SortSpec;
import com.nebutown.generation.basictype.UID;
import com.nebutown.supporthome.AbstractIndex;

import java.sql.ResultSet;
import java.util.List;
import java.util.Map;

public class ConsumptionListImpl extends AbstractIndex<ConsumptionListCriteria, ConsumptionListBean> {

    @Override
    public String getTableName() {
        return "" + getConnectionName() + ".CONSUMPTIONLIST";
    }

    @Override
    public ConsumptionListBean newBean() {
        return new ConsumptionListBean();
    }

    @Override
    public ConsumptionListCriteria newCriteria() {
        return new ConsumptionListCriteria();
    }

    @Override
    public List<String> getFieldNames() {
        return Lists.newArrayList(
                "consumptionUid",
                "totalPrice",
                "finalPrice",
                "time",
                "shopUID",
                "shopName",
                "accumulatePoints",
                "customerUid",
                "customerName",
                "weChatId");
    }

    @Override
    public List<String> getDateFields() {
        return Lists.newArrayList(
                "time",
                "accumulatePoints");
    }

    @Override
    public List<String> getDoubleFields() {
        return Lists.newArrayList(
                "totalPrice",
                "finalPrice");
    }

    @Override
    public Map<String, String> getFieldLabels() {
        return ImmutableMap.<String, String>builder()
                .put("totalPrice", "总价")
                .put("finalPrice", "最终价格")
                .put("time", "支付时间")
                .put("shopUID", "门店")
                .put("shopName", "门店的名字")
                .put("accumulatePoints", "获得的积分")
                .put("customerName", "客户名")
                .put("weChatId", "客户微信Id")
                .build();
    }

    @Override
    public List<String> getContributors() {
        return Lists.newArrayList(
                "com.restaurant.application.consumption.Consumption",
                "com.restaurant.application.genshanguser.GenShangUser");
    }

    @Override
    public ConsumptionListBean fakeBean() {
        ConsumptionListBean bean = new ConsumptionListBean();

        bean.setConsumptionUid(UID.recover("A 9059774725974720871 looooong string"));
        bean.setTotalPrice(0.37230275437349214);
        bean.setFinalPrice(0.4075514224539105);
        bean.setTime(-1053082591L);
        bean.setShopUID("A -473328327585894275 looooong string");
        bean.setShopName("A 4912944383694821680 looooong string");
        bean.setAccumulatePoints(1424845278L);
        bean.setCustomerUid(UID.recover("A -2742512018889031242 looooong string"));
        bean.setCustomerName("A -2425919274714412666 looooong string");
        bean.setWeChatId("A -2426893619652379467 looooong string");
        return bean;
    }

    @Override
    public String getCreateTableStatement() {
        StringBuilder buf = new StringBuilder();

        buf.append("CREATE TABLE IF NOT EXISTS " + getConnectionName() + ".CONSUMPTIONLIST (\n");
        buf.append("    RECORD_ID BIGINT AUTO_INCREMENT,\n");
        buf.append("    CONSUMPTIONUID CHAR(128) CHARACTER SET latin1 COLLATE latin1_general_cs NOT NULL,\n");
        buf.append("    TOTALPRICE REAL,\n");
        buf.append("    FINALPRICE REAL,\n");
        buf.append("    TIME BIGINT,\n");
        buf.append("    SHOPUID VARCHAR(255),\n");
        buf.append("    SHOPNAME VARCHAR(255),\n");
        buf.append("    ACCUMULATEPOINTS BIGINT,\n");
        buf.append("    CUSTOMERUID CHAR(128) CHARACTER SET latin1 COLLATE latin1_general_cs NOT NULL,\n");
        buf.append("    CUSTOMERNAME VARCHAR(255),\n");
        buf.append("    WECHATID VARCHAR(255),\n");
        buf.append("PRIMARY KEY (RECORD_ID)) CHARACTER SET  = utf8mb4 COLLATE = utf8mb4_bin");
        return buf.toString();
    }

    @Override
    public String getInsertDataStatement(ConsumptionListBean data) {
        StringBuilder buf = new StringBuilder();

        buf.append("INSERT INTO " + getConnectionName() + ".CONSUMPTIONLIST (\n    ");
        buf.append("    CONSUMPTIONUID, TOTALPRICE, FINALPRICE, TIME, SHOPUID, SHOPNAME, ACCUMULATEPOINTS, CUSTOMERUID, CUSTOMERNAME, WECHATID");
        buf.append(") VALUES (");
        buf.append("    '" + cut(data.getConsumptionUid(), 128) + "', " + data.getTotalPrice() + ", " + data.getFinalPrice() + ", " + data.getTime() + ", '" + cut(data.getShopUID(), 255) + "', '" + cut(data.getShopName(), 255) + "', " + data.getAccumulatePoints() + ", '" + cut(data.getCustomerUid(), 128) + "', '" + cut(data.getCustomerName(), 255) + "', '" + cut(data.getWeChatId(), 255) + "'");
        buf.append(")");
        return buf.toString();
    }

    @Override
    public String getDeleteRowsStatement(Long rowId) {
        return "DELETE FROM " + getConnectionName() + ".CONSUMPTIONLIST WHERE  RECORD_ID = " + rowId;
    }

    @Override
    public String getLocalUpdateStatement(ConsumptionListBean data) {
        StringBuilder buf = new StringBuilder();
        StringBuilder sep = new StringBuilder();

        boolean hasData = false;

        buf.append("UPDATE " + getConnectionName() + ".CONSUMPTIONLIST \n");
        buf.append("   SET ");
        if(data.getConsumptionUid() != null) {
            buf.append(sep.toString() + "\n      CONSUMPTIONUID = '" + cut(data.getConsumptionUid(), 128) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getTotalPrice() != null) {
            buf.append(sep.toString() + "\n      TOTALPRICE = " + data.getTotalPrice() + "");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getFinalPrice() != null) {
            buf.append(sep.toString() + "\n      FINALPRICE = " + data.getFinalPrice() + "");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getTime() != null) {
            buf.append(sep.toString() + "\n      TIME = " + data.getTime() + "");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getShopUID() != null) {
            buf.append(sep.toString() + "\n      SHOPUID = '" + cut(data.getShopUID(), 255) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getShopName() != null) {
            buf.append(sep.toString() + "\n      SHOPNAME = '" + cut(data.getShopName(), 255) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getAccumulatePoints() != null) {
            buf.append(sep.toString() + "\n      ACCUMULATEPOINTS = " + data.getAccumulatePoints() + "");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getCustomerUid() != null) {
            buf.append(sep.toString() + "\n      CUSTOMERUID = '" + cut(data.getCustomerUid(), 128) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getCustomerName() != null) {
            buf.append(sep.toString() + "\n      CUSTOMERNAME = '" + cut(data.getCustomerName(), 255) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getWeChatId() != null) {
            buf.append(sep.toString() + "\n      WECHATID = '" + cut(data.getWeChatId(), 255) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(!hasData) return "";

        hasData = false;
        buf.append(" WHERE TRUE\n");
        if(data.getConsumptionUid() != null) {
            buf.append("    AND CONSUMPTIONUID = '" + data.getConsumptionUid() + "'\n");
            hasData = true;
        }
        if(data.getCustomerUid() != null) {
            buf.append("    AND CUSTOMERUID = '" + data.getCustomerUid() + "'\n");
            hasData = true;
        }
        if(!hasData) return "";

        return buf.toString();
    }

    @Override
    public String getUpdateByIdStatement(ConsumptionListBean data) {
        StringBuilder buf = new StringBuilder();
        StringBuilder sep = new StringBuilder();

        boolean hasData = false;

        buf.append("UPDATE " + getConnectionName() + ".CONSUMPTIONLIST \n");
        buf.append("   SET ");
        if(data.getConsumptionUid() != null) {
            buf.append(sep.toString() + "\n      CONSUMPTIONUID = '" + cut(data.getConsumptionUid(), 128) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getTotalPrice() != null) {
            buf.append(sep.toString() + "\n      TOTALPRICE = " + data.getTotalPrice() + "");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getFinalPrice() != null) {
            buf.append(sep.toString() + "\n      FINALPRICE = " + data.getFinalPrice() + "");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getTime() != null) {
            buf.append(sep.toString() + "\n      TIME = " + data.getTime() + "");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getShopUID() != null) {
            buf.append(sep.toString() + "\n      SHOPUID = '" + cut(data.getShopUID(), 255) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getShopName() != null) {
            buf.append(sep.toString() + "\n      SHOPNAME = '" + cut(data.getShopName(), 255) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getAccumulatePoints() != null) {
            buf.append(sep.toString() + "\n      ACCUMULATEPOINTS = " + data.getAccumulatePoints() + "");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getCustomerUid() != null) {
            buf.append(sep.toString() + "\n      CUSTOMERUID = '" + cut(data.getCustomerUid(), 128) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getCustomerName() != null) {
            buf.append(sep.toString() + "\n      CUSTOMERNAME = '" + cut(data.getCustomerName(), 255) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getWeChatId() != null) {
            buf.append(sep.toString() + "\n      WECHATID = '" + cut(data.getWeChatId(), 255) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(!hasData) return "";

        hasData = false;
        buf.append(" WHERE RECORD_ID = " + data.getRecordId());
        return buf.toString();
    }

    @Override
    public ConsumptionListBean extractLine(ResultSet resultSet) throws Exception {
        ConsumptionListBean result = new ConsumptionListBean();

        result.setRecordId(resultSet.getLong("RECORD_ID"));
        result.setConsumptionUid(UID.recover(resultSet.getString("consumptionUid")));
        result.setTotalPrice(resultSet.getDouble("totalPrice"));
        result.setFinalPrice(resultSet.getDouble("finalPrice"));
        result.setTime(resultSet.getLong("time"));
        result.setShopUID(resultSet.getString("shopUID"));
        result.setShopName(resultSet.getString("shopName"));
        result.setAccumulatePoints(resultSet.getLong("accumulatePoints"));
        result.setCustomerUid(UID.recover(resultSet.getString("customerUid")));
        result.setCustomerName(resultSet.getString("customerName"));
        result.setWeChatId(resultSet.getString("weChatId"));
        return result;
    }

    @Override
    public String getWherePart(ConsumptionListCriteria criteria, SortSpec sort) {
        StringBuilder buf = new StringBuilder(" TRUE ");

        criteria.setShopUIDLike(searchString(criteria.getShopUIDLike()));
        criteria.setShopNameLike(searchString(criteria.getShopNameLike()));
        criteria.setCustomerNameLike(searchString(criteria.getCustomerNameLike()));
        criteria.setWeChatIdLike(searchString(criteria.getWeChatIdLike()));

        if(criteria.getRecordId() != null) {
            buf.append("    AND RECORD_ID = " + criteria.getRecordId());
        }
        if(criteria.getConsumptionUidEquals() != null) {
            buf.append("    AND CONSUMPTIONUID = '" + criteria.getConsumptionUidEquals() + "'");
        }
        if(criteria.getConsumptionUidNotEquals() != null) {
            buf.append("    AND CONSUMPTIONUID != '" + criteria.getConsumptionUidNotEquals() + "'");
        }
        if(criteria.getTotalPriceUpper() != null) {
            buf.append("    AND TOTALPRICE <= " + criteria.getTotalPriceUpper());
        }
        if(criteria.getTotalPriceLower() != null) {
            buf.append("    AND TOTALPRICE >= " + criteria.getTotalPriceLower());
        }
        if(criteria.getFinalPriceUpper() != null) {
            buf.append("    AND FINALPRICE <= " + criteria.getFinalPriceUpper());
        }
        if(criteria.getFinalPriceLower() != null) {
            buf.append("    AND FINALPRICE >= " + criteria.getFinalPriceLower());
        }
        if(criteria.getTimeUpper() != null) {
            buf.append("    AND TIME <= " + criteria.getTimeUpper());
        }
        if(criteria.getTimeLower() != null) {
            buf.append("    AND TIME >= " + criteria.getTimeLower());
        }
        if(criteria.getTimeEquals() != null) {
            buf.append("    AND TIME = '" + criteria.getTimeEquals() + "'");
        }
        if(criteria.getTimeNotEquals() != null) {
            buf.append("    AND TIME != '" + criteria.getTimeNotEquals() + "'");
        }
        if(!Strings.isNullOrEmpty(criteria.getShopUIDEquals())) {
            buf.append("    AND SHOPUID = '" + cut(criteria.getShopUIDEquals()) + "'");
        }
        if(!Strings.isNullOrEmpty(criteria.getShopUIDNotEquals())) {
            buf.append("    AND SHOPUID != '" + cut(criteria.getShopUIDNotEquals()) + "'");
        }
        if(!Strings.isNullOrEmpty(criteria.getShopUIDLike())) {
            buf.append("    AND SHOPUID LIKE '" + cut(criteria.getShopUIDLike()) + "'");
        }
        if(!Strings.isNullOrEmpty(criteria.getShopNameEquals())) {
            buf.append("    AND SHOPNAME = '" + cut(criteria.getShopNameEquals()) + "'");
        }
        if(!Strings.isNullOrEmpty(criteria.getShopNameNotEquals())) {
            buf.append("    AND SHOPNAME != '" + cut(criteria.getShopNameNotEquals()) + "'");
        }
        if(!Strings.isNullOrEmpty(criteria.getShopNameLike())) {
            buf.append("    AND SHOPNAME LIKE '" + cut(criteria.getShopNameLike()) + "'");
        }
        if(criteria.getAccumulatePointsUpper() != null) {
            buf.append("    AND ACCUMULATEPOINTS <= " + criteria.getAccumulatePointsUpper());
        }
        if(criteria.getAccumulatePointsLower() != null) {
            buf.append("    AND ACCUMULATEPOINTS >= " + criteria.getAccumulatePointsLower());
        }
        if(criteria.getAccumulatePointsEquals() != null) {
            buf.append("    AND ACCUMULATEPOINTS = '" + criteria.getAccumulatePointsEquals() + "'");
        }
        if(criteria.getAccumulatePointsNotEquals() != null) {
            buf.append("    AND ACCUMULATEPOINTS != '" + criteria.getAccumulatePointsNotEquals() + "'");
        }
        if(criteria.getCustomerUidEquals() != null) {
            buf.append("    AND CUSTOMERUID = '" + criteria.getCustomerUidEquals() + "'");
        }
        if(criteria.getCustomerUidNotEquals() != null) {
            buf.append("    AND CUSTOMERUID != '" + criteria.getCustomerUidNotEquals() + "'");
        }
        if(!Strings.isNullOrEmpty(criteria.getCustomerNameEquals())) {
            buf.append("    AND CUSTOMERNAME = '" + cut(criteria.getCustomerNameEquals()) + "'");
        }
        if(!Strings.isNullOrEmpty(criteria.getCustomerNameNotEquals())) {
            buf.append("    AND CUSTOMERNAME != '" + cut(criteria.getCustomerNameNotEquals()) + "'");
        }
        if(!Strings.isNullOrEmpty(criteria.getCustomerNameLike())) {
            buf.append("    AND CUSTOMERNAME LIKE '" + cut(criteria.getCustomerNameLike()) + "'");
        }
        if(!Strings.isNullOrEmpty(criteria.getWeChatIdEquals())) {
            buf.append("    AND WECHATID = '" + cut(criteria.getWeChatIdEquals()) + "'");
        }
        if(!Strings.isNullOrEmpty(criteria.getWeChatIdNotEquals())) {
            buf.append("    AND WECHATID != '" + cut(criteria.getWeChatIdNotEquals()) + "'");
        }
        if(!Strings.isNullOrEmpty(criteria.getWeChatIdLike())) {
            buf.append("    AND WECHATID LIKE '" + cut(criteria.getWeChatIdLike()) + "'");
        }
        if(sort != null && sort.getColumns().size() > 0) {
            buf.append(" ORDER BY ");
            sort.getColumns().forEach(c->buf.append(c.getColumnName().toUpperCase())
                .append(" ").append((c.getAscending() != null && c.getAscending()) ? "ASC" : "DESC")
                .append(", "));
            buf.append("RECORD_ID ASC");
        }
        return buf.toString();
    }

    @Override
    public <T extends Unit > String getUpdateStatement(T source) {
        ConsumptionListBean data = null;

        if(source instanceof com.restaurant.application.indexes.consumptionlist.mysql.ConsumptionListFromconsumptionUidIF) {
            data = new ConsumptionListBean();
             ((com.restaurant.application.indexes.consumptionlist.mysql.ConsumptionListFromconsumptionUidIF)source).getConsumptionUidDataForConsumptionList(data);
        }
        if(source instanceof com.restaurant.application.indexes.consumptionlist.mysql.ConsumptionListFromcustomerUidIF) {
            data = new ConsumptionListBean();
             ((com.restaurant.application.indexes.consumptionlist.mysql.ConsumptionListFromcustomerUidIF)source).getCustomerUidDataForConsumptionList(data);
        }

        return data == null ? null: getLocalUpdateStatement(data);
    }
}
